package com.framework.auth.config;

import org.springframework.context.annotation.Configuration;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

@Configuration
public class AuthConfig {

    private final String loginType;
    private final String userServiceUrl;
    private final List<String> authPaths;
    private final String localServiceClass;

    private final int maxConnections;
    private final int connectTimeout;
    private final int readTimeout;
    private final int writeTimeout;
    private final boolean retryOnConnectionFailure;
    private final int keepAliveDuration;

    public AuthConfig() throws IOException, ParserConfigurationException, SAXException {
        // 读取 login.xml 配置文件
        InputStream xmlInput = loadConfigFile();

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(xmlInput);

        // 获取 loginType 配置（http 或 local）
        this.loginType = getElementValue(doc, "loginType", "http");

        // 获取本地服务类全路径
        this.localServiceClass = getElementValue(doc, "localServiceClass", "");

        // 获取需要鉴权的路径列表
        NodeList pathNodes = doc.getElementsByTagName("path");
        authPaths = new ArrayList<>();
        for (int i = 0; i < pathNodes.getLength(); i++) {
            authPaths.add(pathNodes.item(i).getTextContent());
        }

        // 获取用户服务 URL
        this.userServiceUrl = getElementValue(doc, "userServiceUrl", "");

        // 解析 OkHttp 配置
        Node okHttpNode = doc.getElementsByTagName("okHttp").item(0);
        this.maxConnections = Integer.parseInt(getElementValue(okHttpNode, "maxConnections", "50"));
        this.connectTimeout = Integer.parseInt(getElementValue(okHttpNode, "connectTimeout", "10"));
        this.readTimeout = Integer.parseInt(getElementValue(okHttpNode, "readTimeout", "30"));
        this.writeTimeout = Integer.parseInt(getElementValue(okHttpNode, "writeTimeout", "30"));
        this.retryOnConnectionFailure = Boolean.parseBoolean(getElementValue(okHttpNode, "retryOnConnectionFailure", "true"));
        this.keepAliveDuration = Integer.parseInt(getElementValue(okHttpNode, "keepAliveDuration", "60"));  // 新增的 keepAliveDuration
    }

    /**
     * 加载配置文件，基于环境变量 `current_model` 来选择文件
     *
     * @return InputStream 配置文件的输入流
     * @throws IOException 如果文件未找到，抛出异常
     */
    public InputStream loadConfigFile() throws IOException {
        // 获取环境变量 current_model
        String currentModel = System.getProperty("current_model", "prod"); // 默认值为 "prod"

        // 构建配置文件的路径
        String configFilePath = "config/login/login_" + currentModel + ".xml";

        // 获取配置文件输入流
        InputStream xmlInput = getClass().getClassLoader().getResourceAsStream(configFilePath);

        // 如果文件未找到，抛出异常
        if (xmlInput == null) {
            throw new IOException(configFilePath + " not found");
        }

        return xmlInput;
    }

    // 获取 XML 元素的值，支持默认值
    private String getElementValue(Node parentNode, String tagName, String defaultValue) {
        NodeList nodeList = parentNode.getChildNodes();
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node node = nodeList.item(i);
            if (node.getNodeName().equals(tagName)) {
                return node.getTextContent();
            }
        }
        return defaultValue;
    }

    // 获取 XML 元素的值，支持默认值
    private String getElementValue(Document doc, String tagName, String defaultValue) {
        NodeList nodeList = doc.getElementsByTagName(tagName);
        if (nodeList.getLength() > 0) {
            Node node = nodeList.item(0);
            return node.getTextContent();
        }
        return defaultValue;
    }

    public String getLoginType() {
        return loginType;
    }

    public String getUserServiceUrl() {
        return userServiceUrl;
    }

    public List<String> getAuthPaths() {
        return authPaths;
    }

    public String getLocalServiceClass() {
        return localServiceClass;
    }

    public int getMaxConnections() {
        return maxConnections;
    }

    public int getConnectTimeout() {
        return connectTimeout;
    }

    public int getReadTimeout() {
        return readTimeout;
    }

    public int getWriteTimeout() {
        return writeTimeout;
    }

    public boolean isRetryOnConnectionFailure() {
        return retryOnConnectionFailure;
    }

    public int getKeepAliveDuration() {
        return keepAliveDuration;
    }
}
